package com.magold.logic.pipe;

import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.AlphaModifier;
import org.andengine.entity.shape.IAreaShape;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.util.adt.pool.PoolItem;

import com.magold.context.IContext;
import com.magold.context.IFixedEngine;
import com.magold.logic.LogicConstants;
import com.magold.sprite.MultiTextureSprite;

public class Halo extends PoolItem implements IUpdateHandler {

	// static value.
	public static abstract class Constants extends LogicConstants {
		protected ITiledTextureRegion sRegion;
		protected float WIDTH;
		protected float HEIGHT;
		
		public Constants(IContext pActivity) {
			super(pActivity);
		}
	}
	
	private static Constants sConstants;
	public static void customize(Constants pConstants) {
		sConstants = pConstants;
	}
	//===============================================================
	private static final float ALPHA_SPEED = 0.5f;
	
	private AlphaModifier mAlphaModifier;
	private MultiTextureSprite mHaloSprite;
	private IAreaShape mShape;
	private boolean mExpire;
	
	boolean visited;
	
	public Halo(VertexBufferObjectManager pVBOM) {
		this(null, pVBOM);
	}
	
	public Halo(IAreaShape pShape, VertexBufferObjectManager pVBOM) {
		ITiledTextureRegion region = sConstants.sRegion.deepCopy();
		mHaloSprite = new MultiTextureSprite(0, 0, sConstants.WIDTH, sConstants.HEIGHT, 0, region, pVBOM);
		mAlphaModifier = new AlphaModifier(0.5f, 0, 1);
		mHaloSprite.registerUpdateHandler(this);
		
		IFixedEngine engine = sConstants.mContext.getEngine();
		engine.registerChildToScene(mHaloSprite, engine.getScene());
		setFollowingShape(pShape);
	}
	
	@Override
	protected void onRecycle() {
		this.reset();
	}
	
	public void setFollowingShape(IAreaShape pShape) {
		mShape = pShape;
		
		// init mHaloSprite's position.
		onUpdate(0);
		
		boolean visible = (mShape!=null);
		mHaloSprite.setVisible(visible);
	}
	
	public IEntity getSprite() {
		return mHaloSprite;
	}
	
	@Override
	public void reset() {
		mHaloSprite.reset();	// remove this from mHaloSprite.
		
		setFollowingShape(null);
	}

	@Override
	public void onUpdate(float pSecondsElapsed) {
		if (mShape == null) return;

		float x = mShape.getX();
		float y = mShape.getY();
		float w = mShape.getWidthScaled();
		float h = mShape.getHeightScaled();

		float hw = mHaloSprite.getWidthScaled();
		float hh = mHaloSprite.getHeightScaled();
		mHaloSprite.setPosition(x + w/2 - hw/2, y + h/2 - hh/2);
	}

	public void disappear() {
		float from = mShape.getAlpha();
		float delta = from - 0;
		
		mAlphaModifier.reset(delta / ALPHA_SPEED, from, 0);
		
		registerSafely();
		
		mExpire = true;
	}
	
	private void registerSafely() {
		mHaloSprite.unregisterEntityModifier(mAlphaModifier);
		mHaloSprite.registerEntityModifier(mAlphaModifier);
	}

	public void appear() {
		float from = mShape.getAlpha();
		float delta = 1 - from;
		mAlphaModifier.reset(delta / ALPHA_SPEED, from, 1);
		
		mExpire = false;
	}

	public boolean expire() {
		return mExpire;
	}
	
}
